<template>
  <div class="canvas-container">
    <div class="canvas-header">
      <div class="canvas-tools">
        <el-button @click="$emit('clear-canvas')" type="danger" size="small"
          >清空画布</el-button
        >
        <el-button @click="$emit('preview-form')" type="primary" size="small"
          >预览表单</el-button
        >
        <el-button @click="$emit('save-form')" type="success" size="small"
          >保存表单</el-button
        >
      </div>
    </div>
    <div
      ref="canvasRef"
      class="canvas"
      v-loading="loading"
      element-loading-text="加载中..."
      @drop="$emit('drop', $event)"
      @dragover="handleDragOver"
      @dragenter="handleDragEnter"
      @dragleave="handleDragLeave"
      @click.self="handleCanvasClick"
    >
      <div style="position: relative; height: 1200px;">
        <!-- 对齐线 -->
        <div
          v-if="alignmentGuides.vertical !== null"
          class="alignment-guide vertical"
          :style="{ left: alignmentGuides.vertical + 'px' }"
        ></div>
        <div
          v-if="alignmentGuides.horizontal !== null"
          class="alignment-guide horizontal"
          :style="{ top: alignmentGuides.horizontal + 'px' }"
        ></div>

        <!-- 拖拽阴影预览 -->
        <div
          v-if="dragShadow?.visible"
          class="drag-shadow"
          :style="{
            left: dragShadow.x + 'px',
            top: dragShadow.y + 'px',
            width: dragShadow.width,
            height: dragShadow.height,
          }"
        >
          <div class="drag-shadow-content">组件预览</div>
        </div>

        <!-- 渲染的组件 -->
        <div
          v-for="component in allComponents.filter((c) => !c.parentId)"
          :key="component.id"
          :class="[
            'canvas-component',
            {
              active: selectedComponent?.id === component.id,
              colliding: component.isColliding,
              // 栅格悬浮高亮交由 FormComponent 内部按 grid-item 控制
            },
          ]"
          :style="{
            left: component.position.x + 'px',
            top: component.position.y + 'px',
            width: getComponentWidth(component),
            // minHeight: component.size.height + 'px',
            height: component.size.height + 'px',
          }"
          @mousedown="$emit('start-drag', $event, component)"
        >
          <!-- 使用独立的工具栏组件 -->
          <ComponentToolbar
            v-if="showBar(component)"
            :component="component"
            :variant="'floating'"
          />
          <FormComponent
            :component="component"
            :mutex-state="props.mutexState"
            :relate-state="props.relateState"
            :is-preview="false"
            :drag-hover-state="props.dragHoverState"
            :selectedComponent="selectedComponent"
            @select-component="handleSelectComponent"
            @click="handleSelectComponent(component, $event)"
          />

          <!-- 调整手柄（仅在选中时显示） -->
          <div
            v-if="selectedComponent?.id === component.id"
            class="resize-handles"
          >
            <!-- 上边调整手柄 -->
            <div
              class="resize-handle resize-handle-top"
              @mousedown.stop="startResize($event, component, 'top')"
            ></div>
            <!-- 右边调整手柄 -->
            <div
              class="resize-handle resize-handle-right"
              @mousedown.stop="startResize($event, component, 'right')"
            ></div>
            <!-- 下边调整手柄 -->
            <div
              class="resize-handle resize-handle-bottom"
              @mousedown.stop="startResize($event, component, 'bottom')"
            ></div>
            <!-- 左边调整手柄 -->
            <div
              class="resize-handle resize-handle-left"
              @mousedown.stop="startResize($event, component, 'left')"
            ></div>
            <!-- 左上角调整手柄 -->
            <div
              class="resize-handle resize-handle-top-left"
              @mousedown.stop="startResize($event, component, 'top-left')"
            ></div>
            <!-- 右上角调整手柄 -->
            <div
              class="resize-handle resize-handle-top-right"
              @mousedown.stop="startResize($event, component, 'top-right')"
            ></div>
            <!-- 左下角调整手柄 -->
            <div
              class="resize-handle resize-handle-bottom-left"
              @mousedown.stop="startResize($event, component, 'bottom-left')"
            ></div>
            <!-- 右下角调整手柄 -->
            <div
              class="resize-handle resize-handle-bottom-right"
              @mousedown.stop="startResize($event, component, 'bottom-right')"
            ></div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from "vue";
import FormComponent from "./FormComponent.vue";
import type { CanvasComponent, AlignmentGuides, RelateConfig } from "../types";
import ComponentToolbar from "./ComponentToolbar.vue";

interface Props {
  allComponents: CanvasComponent[];
  selectedComponent: CanvasComponent | null;
  alignmentGuides: AlignmentGuides;
  mutexState?: Map<string, boolean>;
  relateState?: RelateConfig[];
  loading?: boolean;
  dragHoverState?: {
    isHovering: boolean;
    gridComponent: CanvasComponent | null;
    gridItemIndex: number;
  };
  dragShadow?: {
    visible: boolean;
    x: number;
    y: number;
    width: number | string;
    height: number | string;
  };
}

const props = withDefaults(defineProps<Props>(), {
  mutexState: () => new Map(),
  relateState: () => [],
  loading: false,
  dragHoverState: () => ({
    isHovering: false,
    gridComponent: null,
    gridItemIndex: -1,
  }),
  dragShadow: () => ({
    visible: false,
    x: 0,
    y: 0,
    width: '100%',
    height: '30px',
  }),
});

const emit = defineEmits<{
  drop: [event: DragEvent];
  "start-drag": [event: MouseEvent, component: CanvasComponent];
  "start-resize": [
    event: MouseEvent,
    component: CanvasComponent,
    direction: string
  ];
  "clear-canvas": [];
  "preview-form": [];
  "save-form": [];
  "export-json": [];
  "clear-selection": [];
  "drag-hover": [data: { x: number; y: number; event: DragEvent }];
  "drag-leave": [event: DragEvent];
  "select-child-component": [component: CanvasComponent];
}>();

const canvasRef = ref<HTMLElement>();

// 处理选中子组件
const handleSelectComponent = (component: CanvasComponent, event: Event) => {
  // 阻止事件冒泡
  event?.stopPropagation();
  console.log("CanvasArea 处理选中子组件:", component);
  // 触发选中组件事件
  emit("select-child-component", component);
};

const showBar = (component: CanvasComponent): boolean => {
  // 如果没有选中组件，不显示工具栏
  if (!props.selectedComponent) return false;

  // 判断是否是选中的组件本身
  const isSameComponent = component.id === props.selectedComponent.id;

  // 判断是否是选中组件的子组件
  const isChildComponent =
    component?.children?.some(
      (child) => child.id === props.selectedComponent?.id
    ) || false;

  return isSameComponent && !isChildComponent;
};

// 拖拽进入画布
const handleDragEnter = (event: DragEvent) => {
  event.preventDefault();
};

// 拖拽经过画布
const handleDragOver = (event: DragEvent) => {
  event.preventDefault();
  if (event.dataTransfer) {
    event.dataTransfer.dropEffect = "copy";
  }

  // 检查是否拖拽到栅格组件上
  const canvasEl = canvasRef.value;
  const canvasRect = canvasEl?.getBoundingClientRect();
  if (canvasRect) {
    const scrollLeft = canvasEl?.scrollLeft || 0;
    const scrollTop = canvasEl?.scrollTop || 0;
    const x = event.clientX - canvasRect.left + scrollLeft;
    const y = event.clientY - canvasRect.top + scrollTop;

    // 发出拖拽悬停事件
    emit("drag-hover", { x, y, event });
  }
};

// 拖拽离开画布
const handleDragLeave = (event: DragEvent) => {
  // 发出拖拽离开事件
  emit("drag-leave", event);
};

// 点击画布空白区域
const handleCanvasClick = (event: MouseEvent) => {
  // 检查点击的是否为画布本身（而不是子组件）
  if (event.target === event.currentTarget) {
    emit("clear-selection");
  }
};

// 开始调整尺寸
const startResize = (
  event: MouseEvent,
  component: CanvasComponent,
  direction: string
) => {
  console.log("startResize:", event, component, direction);
  emit("start-resize", event, component, direction);
};

// 宽度计算节流缓存
const WIDTH_THROTTLE_MS = 1000;
const widthCache = ref(new Map<string, { value: string; ts: number }>());

// 获取组件宽度（节流）
const getComponentWidth = (component: CanvasComponent) => {
  const cache = widthCache.value.get(component.id);
  const now = Date.now();
  if (cache && now - cache.ts < WIDTH_THROTTLE_MS) {
    return cache.value;
  }

  let widthValue: string;
  if (component.props.widthType === "custom" && component.props.customWidth) {
    widthValue = component.props.customWidth + "px";
  } else if (component.props.widthType === "full") {
    widthValue = "100%";
  } else {
    widthValue = component.size.width + "px";
  }

  widthCache.value.set(component.id, { value: widthValue, ts: now });
  return widthValue;
};

// 获取画布边界信息
const getCanvasRect = () => {
  return canvasRef.value?.getBoundingClientRect();
};

defineExpose({
  getCanvasRect,
});
</script>

<style scoped lang="scss">
.canvas-container {
  flex: 1;
  display: flex;
  flex-direction: column;

  .canvas-header {
    height: 55px;
    background: white;
    border-bottom: 1px solid #e4e7ed;
    display: flex;
    align-items: center;
    padding: 0 16px;

    .canvas-tools {
      display: flex;
      gap: 8px;
    }
  }

  .canvas {
    flex: 1;
    position: relative;
    background: white;
    margin: 16px;
    border: 2px dashed #e4e7ed;
    border-radius: 4px;
    overflow: auto;
    -ms-overflow-style: none; // IE/Edge
    scrollbar-width: none; // Firefox

    &::-webkit-scrollbar {
      // Chrome/Safari
      display: none;
      width: 0;
      height: 0;
      background: transparent;
    }

    &:hover {
      border-color: #409eff;
    }

    // 对齐线
    .alignment-guide {
      position: absolute;
      background-color: #409eff;
      z-index: 1000;
      pointer-events: none;

      &.vertical {
        width: 1px;
        height: 100%;
        top: 0;
      }

      &.horizontal {
        height: 1px;
        width: 100%;
        left: 0;
      }
    }

    // 画布中的组件
    .canvas-component {
      position: absolute;
      border: 1px dashed transparent;
      border-radius: 4px;
      cursor: move;
      padding: 2px;
      box-sizing: border-box;
      display: flex;
      align-items: center;

      &.active {
        border-color: #409eff;
        z-index: 999;
      }

      &.colliding {
        border-color: #f56c6c !important;
        border-style: solid !important;
        border-width: 2px !important;
        box-shadow: 0 0 8px rgba(245, 108, 108, 0.5);
      }

      &.grid-hover {
        border-color: #67c23a !important;
        border-style: solid !important;
        border-width: 3px !important;
        box-shadow: 0 0 12px rgba(103, 194, 58, 0.6);
        background-color: rgba(103, 194, 58, 0.1) !important;
        transform: scale(1.02);
        transition: all 0.2s ease;
      }

      // &:hover {
      //   border-color: #409eff;
      // }
      // 调整手柄容器
      .resize-handles {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        pointer-events: none;

        .resize-handle {
          position: absolute;
          background-color: #409eff;
          pointer-events: auto;
          z-index: 10;

          &:hover {
            background-color: #1890ff;
          }

          // 上边调整手柄
          &.resize-handle-top {
            top: -2px;
            left: 50%;
            width: 30px;
            height: 2px;
            transform: translateX(-50%);
            cursor: ns-resize;
          }

          // 右边调整手柄
          &.resize-handle-right {
            top: 50%;
            right: -2px;
            width: 2px;
            height: 30px;
            transform: translateY(-50%);
            cursor: ew-resize;
          }

          // 下边调整手柄
          &.resize-handle-bottom {
            bottom: -2px;
            left: 50%;
            width: 30px;
            height: 2px;
            transform: translateX(-50%);
            cursor: ns-resize;
          }

          // 左边调整手柄
          &.resize-handle-left {
            top: 50%;
            left: -2px;
            width: 2px;
            height: 30px;
            transform: translateY(-50%);
            cursor: ew-resize;
          }

          // 左上角调整手柄
          &.resize-handle-top-left {
            top: -2px;
            left: -2px;
            width: 4px;
            height: 4px;
            cursor: nw-resize;
          }

          // 右上角调整手柄
          &.resize-handle-top-right {
            top: -2px;
            right: -2px;
            width: 4px;
            height: 4px;
            cursor: ne-resize;
          }

          // 左下角调整手柄
          &.resize-handle-bottom-left {
            bottom: -2px;
            left: -2px;
            width: 4px;
            height: 4px;
            cursor: ne-resize;
          }

          // 右下角调整手柄
          &.resize-handle-bottom-right {
            bottom: -2px;
            right: -2px;
            width: 4px;
            height: 4px;
            cursor: nw-resize;
          }
        }
      }
    }
  }

  // 拖拽阴影样式
  .drag-shadow {
    position: absolute;
    background-color: rgba(64, 158, 255, 0.3);
    border-radius: 6px;
    pointer-events: none;
    z-index: 9999;
    
    .drag-shadow-content {
      display: flex;
      align-items: center;
      justify-content: center;
      height: 100%;
      color: #409eff;
      font-size: 12px;
      font-weight: bold;
    }
  }
}
</style>
